home *** CD-ROM | disk | FTP | other *** search
/ MACup: Giveaway 1996 / Image.iso / Shareware & Demos / Web-Publishing / SNAP PrimeBase / PrimeBase™ Server PPC / Setup / Scripts / schema.dal < prev    next >
Encoding:
Text File  |  1996-07-14  |  24.5 KB  |  1,058 lines  |  [TEXT/ds30]

  1. declare procedure SchemaHelp()
  2. {
  3. print "Function:    Schema";
  4. print "Author:     Dirk Strack, updated to handle VIEWS by Dieko Jacobi 9/94";
  5. print "Date:        11.6.93 ";
  6. print "Location:    P.INK, Rothenbaumch.5, Hamburg, North-Germany,";
  7. print "Dedicated:    to Iris and all database cowboys.";
  8. print "Description: ";
  9. print "";
  10. print "Schema is a function to print the CREATE statements for a given table name.";
  11. print "the second parameter is optional. if the parameter is omitted, ";
  12. print "schema prints all of the following, if you provide a argument, you can control ";
  13. print "which parts a printed. the characters D, I, R, K, and T define the parts to print.";
  14. print "";
  15. print "    D:    CREATE for simple DOMAINS used with the tables columns.";
  16. print "        CREATE DEFAULTS and RULES on this domains.";
  17. print "        CREATE for composite DOMAINS used to define the tables columns.";
  18. print "    ";
  19. print "    T:    the CREATE table for the given table name.";
  20. print "";
  21. print "    R:    CREATE DEFAULTS and RULES on this table.";
  22. print "";
  23. print "    K:    CREATE for PRIMARY, CANDIDATE KEYS on this table.";
  24. print "        FOREIGN KEYS on this table with explicid and implicid REFERENCES.";
  25. print "        ";
  26. print "    I:    CREATE INDEX on this table.";
  27. print "";
  28. print "";
  29. print "    Examples:";
  30. print "    ";
  31. print '    execute file "Schema" in location "dirk strack:test scripts";';
  32. print "    open database pinkads alias pink;";
  33. print "    ";
  34. print "    /*    print domains used with any table named ads    */";
  35. print '    Schema("ads", "d");';
  36. print "    ";
  37. print "    /*    print all parts of table named ads created by user dbo    */";
  38. print '    Schema("dbo.ads");';
  39. print "";
  40. print "    /*    print all parts of all user tables in the current open database    */";
  41. print "    describe tables;";
  42. print "    for each $cursor Schema(Name);";
  43. print "";
  44. print "    /*    print all parts of all system tables in the current open database    */";
  45. print "    select name from sysobjects ";
  46. print '    where type = "Tab" and creatorname = "System"; ';
  47. print "    for each $cursor Schema(Name);";
  48. print "";
  49. print "xref is a function to print a cross reference list of all columns where ";
  50. print "a given domain is used, or all columns where the domains used in a given table are used.";
  51. print "the function automaticly determinates the type of the given object name.";
  52. print "";
  53. print "    Examples:";
  54. print "    ";
  55. print '    /*    list the usage of domains of table "SysObjects"    */';
  56. print '    xref("SysObjects");';
  57. print "    ";
  58. print '    /*    list the usage if domain "DBObjectID"    */';
  59. print '    xref("DBObjectID");';
  60. print "";
  61. }
  62. end procedure SchemaHelp;
  63.  
  64. declare int maxcolsize = 20;
  65.  
  66. declare procedure colsize(c, i)
  67. returns int;
  68. argument cursor c;
  69. argument int    i;
  70. {
  71.     int    len;
  72.     int    nlen;
  73.  
  74.     len = $colwidth(c,i);
  75.     nlen = $len($colname(c,i));
  76.     if (len < nlen) len = nlen;
  77.     if (len > maxcolsize) len = maxcolsize;
  78.  
  79.     return len;
  80. }
  81. end procedure colsize;
  82.  
  83.  
  84. declare procedure showall(c, size)
  85. argument cursor c = $cursor;
  86. argument int size = 20;
  87. {
  88.     int    i,j;
  89.     int    len;
  90.     maxcolsize = size;
  91.  
  92.     if ($rowcnt is not null)
  93.         print char[10] $rowcnt + " rows selected";
  94.  
  95.     print "";
  96.  
  97.     for (i = 1; i <= $cols(c); i++)
  98.     {
  99.         printf(char[colsize(c, i)] $colname(c,i));
  100.         printf("|");
  101.     }
  102.     print "";
  103.     for (i = 1; i <= $cols(c); i++)
  104.     {
  105.         len = colsize(c, i);
  106.         for (j = 10; j <= len; j = j + 10)
  107.             printf("----------");
  108.         printf($substr("----------", 1, len % 10));
  109.         printf("|");
  110.     }
  111.  
  112.     print "" ;
  113.     for each c
  114.     {
  115.         for (i = 1; i <= $cols(c); i++)
  116.         {
  117.             len = colsize(c,i);
  118.             if (c->:i is null)
  119.                 printf(char[len] "??");
  120.             else
  121.             {
  122.                 switch($coltype(c, i))
  123.                 {
  124.                     case $boolean:
  125.                     switch (int c->:i)
  126.                     {
  127.                         case 0: printf(char[len] "N");
  128.                         break;
  129.                         case 1: printf(char[len] "Y");
  130.                         break;
  131.                         case 2: printf(char[len] "??");
  132.                         break;
  133.                         case 3: printf(char[len] "!!");
  134.                     }
  135.                     break;
  136.                     case $float:
  137.                     case $smfloat:
  138.                         printf(char[len] (decimal[len,3] c->:i));
  139.                     break;
  140.                     case $timestamp:
  141.                         printf(char[len] (varchar c->:i));
  142.                     break;
  143.                     case $varbin:
  144.                         printf("%*X", size, c->:i);
  145.                     break;
  146.                     default:
  147.                         printf(char[len] c->:i);
  148.                 }
  149.             }
  150.             printf("|");
  151.         }
  152.         print "";
  153.     }
  154. }
  155. end procedure showall;
  156.  
  157. declare procedure NameToID(TableName)
  158. returns cursor;
  159. argument varchar TableName;
  160. {
  161.     varchar    CName, TName;
  162.     cursor    ObjCur;
  163.     
  164.     if ($locate(TableName, '.') == 0)
  165.     {
  166.         TName    = TableName;
  167.     
  168.         SELECT    Obj.Type, 
  169.                 Obj.ID,
  170.                 Obj.CreatorName,
  171.                 Obj.Name
  172.         FROM    System.SysObjects Obj
  173.         WHERE    Obj.Name    == :TName
  174.         INTO    ObjCur FOR EXTRACT;
  175.     }
  176.     else
  177.     {
  178.         CName    = $left(TableName, '.');
  179.         TName    = $right(TableName, '.');
  180.         
  181.         SELECT    Obj.Type, 
  182.                 Obj.ID,
  183.                 Obj.CreatorName,
  184.                 Obj.Name
  185.         FROM    System.SysObjects Obj
  186.         WHERE    Obj.DBName    == {:CName, :TName}
  187.         INTO    ObjCur FOR EXTRACT;
  188.     }
  189.     fetch next of ObjCur;
  190.     return ObjCur;
  191. }
  192. end procedure NameToID;
  193.  
  194. declare procedure IDToName(Type, ID)
  195. returns varchar;
  196. argument char[4] Type;
  197. argument integer ID;
  198. {
  199.     cursor    ObjCur;
  200.  
  201.     select    Obj.Name
  202.     from    SysObjects as Obj
  203.     where    Obj.DBID    == {:Type, :ID}
  204.     into    ObjCur;
  205.     fetch next of ObjCur;
  206.     if ($sqlcode == $sqlnotfound)
  207.         return $null;
  208.     else
  209.         return ObjCur->Name;
  210. }
  211. end procedure IDToName;
  212.  
  213. declare procedure RuleExpr(ruletext)
  214. returns varchar;
  215. argument varchar ruletext;
  216. {
  217.     varchar buf1, buf2, c;
  218.     integer pos, length;
  219.     
  220.     pos = $locate($toupper(ruletext), "AS");
  221.     if (pos)
  222.         pos = pos + 3;
  223.     else
  224.     {
  225.         pos = $locate($toupper(ruletext), "CHECK");
  226.         pos = pos + 6;
  227.     }
  228.     buf1 = $substr(ruletext, pos);
  229.     buf1 = $left(buf1, ";");
  230.     length = $len(buf1);
  231.     buf2 = "";
  232.     pos = 1; 
  233.     while (pos <= length)
  234.     {
  235.         c = $substr(buf1, pos, 1);
  236.         if ('!' <= c and c <= "z")
  237.             buf2 = buf2 + c;
  238.         else
  239.             buf2 = buf2 + ' ';
  240.         pos++;
  241.     }
  242.     return buf2;
  243. }
  244. end procedure RuleExpr;
  245.  
  246. declare procedure TypeText(TypeCur)
  247. returns varchar;
  248. argument cursor TypeCur;
  249. {
  250.     varchar text;
  251.     
  252.     text = TypeCur->TypeName;
  253.     if (TypeCur->TypeWithLength)
  254.     {
  255.         text = text + $format("(%d", TypeCur->Length);
  256.         if (TypeCur->TypeWithScale)
  257.             text = text + $format(",%d)", TypeCur->Scale);
  258.         else
  259.             text = text + $format(")");
  260.     }
  261.     return text;
  262. }
  263. end procedure TypeText;
  264.  
  265.  
  266. declare procedure Defaults(ObjCur)
  267. argument cursor ObjCur;
  268. {
  269.     varchar TypeName;
  270.     
  271.     if (ObjCur->ObjType == "Dom")
  272.         TypeName = "DOMAIN";
  273.     else
  274.         TypeName = "COLUMN";
  275.     
  276.     if (ObjCur->DefID is not null)
  277.     {
  278.         if (ObjCur->DefType == 'Ser')
  279.         {
  280.             declare cursor TypeCur;
  281.             
  282.             SELECT    Type.Name                AS TypeName,
  283.                     Type.Scale                AS TypeWithScale,
  284.                     Type.Length                AS TypeWithLength,
  285.                     Var.Scale                AS Scale,
  286.                     Var.Length                AS Length
  287.             FROM    System.SysVariables        AS Var,
  288.                     System.SysDataTypes        AS Type
  289.             WHERE    Var.DBID                == {'Var', ObjCur->DefSerialID}
  290.             AND        Var.DataType            == Type.DataType
  291.             INTO    TypeCur FOR READONLY;
  292.             
  293.             fetch next of TypeCur;
  294.             if ($sqlcode == 0)
  295.             {
  296.                 print "";
  297.                 printf("CREATE COUNTER VARIABLE %s %s;",
  298.                     TypeText(TypeCur),
  299.                     IDToName('Var', ObjCur->DefSerialID));
  300.             }
  301.             else
  302.             {
  303.                 print "";
  304.                 print "/* Error! The COUNTER VARIABLE is missing */";
  305.                 printf("CREATE COUNTER VARIABLE INTEGER %s;",
  306.                     IDToName('Var', ObjCur->DefSerialID));
  307.             }
  308.         }
  309.         print "";
  310.         printf("CREATE DEFAULT %s ON %s %s", 
  311.             IDToName('Def', ObjCur->DefID), TypeName, ObjCur->ObjectName);
  312.         if (TypeName = "COLUMN")
  313.             printf(".%s", ObjCur->ColumnName);
  314.         printf(" AS ");
  315.         switch(ObjCur->DefType)
  316.         {
  317.             case 'Usr':
  318.                 printf("USER");
  319.             break;
  320.             case 'Now':
  321.                 printf("NOW");
  322.             break;
  323.             case 'Ser':
  324.                 printf("SERIAL %s", IDToName('Var', ObjCur->DefSerialID));
  325.             break;
  326.             case 'Lit':
  327.                 switch (ObjCur->DataType)
  328.                 {
  329.                     case $boolean:
  330.                         printf("%s", BOOLEAN ObjCur->DefLiteral);
  331.                         break;
  332.                     case $smint:
  333.                         printf("%d", SMINT ObjCur->DefLiteral);
  334.                         break;
  335.                     case $integer:
  336.                         printf("%d", INTEGER ObjCur->DefLiteral);
  337.                         break;
  338.                     case 20: /* $tinyint: */
  339.                         printf("%d", TINYINT ObjCur->DefLiteral);
  340.                         break;
  341.                     case $smfloat:
  342.                         printf("%f", SMFLOAT ObjCur->DefLiteral);
  343.                         break;
  344.                     case $float:
  345.                         printf("%f", FLOAT ObjCur->DefLiteral);
  346.                         break;
  347.                     case $date:
  348.                         printf("'%s'", DATE ObjCur->DefLiteral);
  349.                         break;
  350.                     case $time:
  351.                         printf("'%s'", TIME ObjCur->DefLiteral);
  352.                         break;
  353.                     case $timestamp:
  354.                         printf("'%s'", TIMESTAMP ObjCur->DefLiteral);
  355.                         break;
  356.                     case $char:
  357.                         printf("'%s'", CHAR ObjCur->DefLiteral);
  358.                         break;
  359.                     case $decimal:
  360.                         printf("'%p'", DECIMAL ObjCur->DefLiteral);
  361.                         break;
  362.                     case $money:
  363.                         printf("'%p'", MONEY ObjCur->DefLiteral);
  364.                         break;
  365.                     case $varchar:
  366.                         printf("'%s'", VARCHAR ObjCur->DefLiteral);
  367.                         break;
  368.                 }
  369.             break;
  370.         }
  371.         printf(";");
  372.     }
  373. }
  374. end procedure Defaults;
  375.  
  376. declare procedure Rules(ObjCur)
  377. argument cursor ObjCur;
  378. {
  379.     varchar TypeName;
  380.     
  381.     if (ObjCur->ObjType == "Dom")
  382.         TypeName = "DOMAIN";
  383.     else
  384.         TypeName = "TABLE";
  385.     
  386.     if (ObjCur->RuleID is not null)
  387.     {
  388.         print "";
  389.         printf("CREATE RULE   %s", IDToName('Rule', ObjCur->RuleID));
  390.         print "";
  391.         printf("    ON %s %s CHECK %s;", 
  392.             TypeName,
  393.             ObjCur->ObjectName,
  394.             RuleExpr(ObjCur->RuleText));
  395.     }
  396. }
  397. end procedure Rules;
  398.  
  399.  
  400. declare procedure TableRuleDefault(ID)
  401. argument integer ID;
  402. {
  403.     declare cursor TabCur;
  404.     
  405.     SELECT    TabObj.Name                AS ObjectName,
  406.             TabObj.Type                AS ObjType,
  407.             Col.Name                AS ColumnName,
  408.             Col.DataType            AS DataType,
  409.             Def.ID                    AS DefID,
  410.             Def.DefaultType            AS DefType,
  411.             Def.Literal                AS DefLiteral,
  412.             Def.SerialID            AS DefSerialID
  413.     FROM    System.SysColumns        AS Col,
  414.             System.SysDefaults        AS Def,
  415.             System.SysObjects        AS TabObj
  416.     WHERE    Col.DBID                == {'Tab', :ID}
  417.     AND        Col.DBColumnID            == Def.DBColumnID
  418.     AND        Col.DBID                == TabObj.DBID
  419.     ORDER    BY ObjectName ASC
  420.     INTO    TabCur FOR READONLY;
  421.  
  422.     for each TabCur
  423.         Defaults(TabCur);
  424.  
  425.     SELECT    TabObj.Name                AS ObjectName,
  426.             TabObj.Type                AS ObjType,
  427.             Rule.ID                    AS RuleID,
  428.             Rule.RuleText            AS RuleText
  429.     FROM    System.SysColumns        AS Col,
  430.             System.SysRules            AS Rule,
  431.             System.SysObjects        AS TabObj
  432.     WHERE    Col.DBID                == {'Tab', :ID}
  433.     AND        Col.DBID                == Rule.DBObjectID
  434.     AND        Col.DBID                == TabObj.DBID
  435.     ORDER    BY ObjectName ASC
  436.     INTO    TabCur FOR READONLY;
  437.  
  438.     for each TabCur
  439.         Rules(TabCur);
  440. }
  441. end procedure TableRuleDefault;
  442.  
  443.  
  444. declare procedure SimpleDomains(ID)
  445. argument integer ID;
  446. {
  447.     declare cursor DomCur;
  448.     declare varchar text;
  449.     /*    find the simple domains with are used in the 
  450.     **    column definitions of the given table ID
  451.     */
  452.     
  453.     SELECT    Dom.Primary                AS Primary,
  454.             DomObj.Name                AS ObjectName,
  455.             DomObj.Type                AS ObjType,
  456.             Type.Name                AS TypeName,
  457.             Type.Scale                AS TypeWithScale,
  458.             Type.Length                AS TypeWithLength,
  459.             Dom.DataType            AS DataType,
  460.             Dom.Scale                AS Scale,
  461.             Dom.Length                AS Length,
  462.             Dom.Nulls                AS Nulls,
  463.             Dom.Arithmetic            AS Arithmetic,
  464.             Dom.Ordered                AS Ordered,
  465.             Dom.SequenceID            AS SequenceID,
  466.             Def.ID                    AS DefID,
  467.             Def.DefaultType            AS DefType,
  468.             Def.Literal                AS DefLiteral,
  469.             Def.SerialID            AS DefSerialID,
  470.             Rule.ID                    AS RuleID,
  471.             Rule.RuleText            AS RuleText
  472.     FROM    System.SysDomains        AS Dom,
  473.             System.SysColumns        AS Col,
  474.             System.SysDataTypes        AS Type,
  475.             System.SysObjects        AS DomObj,
  476.             System.SysDefaults        AS Def,
  477.             System.SysRules            AS Rule
  478.     WHERE    Col.DBID                == {'Tab', :ID}
  479.     AND        Col.ColumnID            <  256
  480.     AND        Col.DBDomainID            == Dom.DBID
  481.     AND        Dom.DataType            == Type.DataType
  482.     AND        Dom.DBID                == DomObj.DBID
  483.     AND        Dom.DBID                /= Def.DBObjectID
  484.     AND        Dom.DBID                /= Rule.DBObjectID
  485.     ORDER    BY ObjectName ASC
  486.     INTO    DomCur FOR READONLY;
  487.  
  488.     for each DomCur
  489.     {
  490.         print "";
  491.         printf("CREATE ");
  492.         if (DomCur->Primary)
  493.             printf("PRIMARY ");    
  494.         printf("DOMAIN %s ", DomCur->ObjectName);
  495.         text = TypeText(DomCur);
  496.         printf(text);
  497.         if (not DomCur->Nulls)
  498.             printf(", NOT NULL");
  499.         else
  500.         if (DomCur->Arithmetic)
  501.             printf(", ARITHMETIC APPLICABLE");
  502.         if (not DomCur->Ordered)
  503.             printf(", ORDER NOT APPLICABLE");
  504.         if (DomCur->SequenceID is not null)
  505.             printf(", ORDER AS COLLATING SEQUENCE %s", IDToName('Var', DomCur->SequenceID));
  506.         printf(";");
  507.         Defaults(DomCur);
  508.         Rules(DomCur);
  509.     }
  510. }
  511. end procedure SimpleDomains;
  512.  
  513. declare procedure CompositeDomains(ID)
  514. argument integer ID;
  515. {
  516.     declare cursor DomCur;
  517.     declare varchar text;
  518.     /*    find the simple domains with are used in the 
  519.     **    column definitions of the given table ID
  520.     */
  521.     SELECT    CDom.Primary            AS Primary,
  522.             CDomObj.Name            AS CDomName,
  523.             CDom.ComponentCnt        AS ComponentCnt,
  524.             DomCom.ComponentID        AS ComponentID,
  525.             Type.Name                AS TypeName,
  526.             Type.Scale                AS TypeWithScale,
  527.             Type.Length                AS TypeWithLength,
  528.             DomCom.Scale            AS Scale,
  529.             DomCom.Length            AS Length,
  530.             SDomObj.Name            AS SDomName
  531.     FROM    System.SysColumns        AS Col,    
  532.             System.SysDomains        AS CDom,
  533.             System.SysObjects        AS CDomObj,
  534.             System.SysDomainComps    AS DomCom,
  535.             System.SysDataTypes        AS Type,
  536.             System.SysObjects        AS SDomObj
  537.     WHERE    Col.DBID                == {'Tab', :ID}
  538.     AND        Col.ColumnID            >=  256
  539.     AND        Col.DBDomainID            == CDom.DBID
  540.     AND        CDom.DBID                == CDomObj.DBID
  541.     AND        CDom.DBID                == DomCom.DBID
  542.     AND        DomCom.DBDomainID        /= SDomObj.DBID
  543.     AND        DomCom.DataType            /= Type.DataType
  544.     ORDER    BY CDomName ASC, ComponentID ASC
  545.     INTO    DomCur FOR READONLY;
  546.     
  547.     for each DomCur
  548.     {
  549.         if (DomCur->ComponentID == 1)
  550.         {
  551.             print "";
  552.             printf("CREATE ");
  553.             if (DomCur->Primary)
  554.                 printf("PRIMARY ");    
  555.             printf("DOMAIN %s (", DomCur->CDomName);
  556.         }
  557.         else
  558.             printf(", ");
  559.         if (DomCur->SDomName is not null)
  560.             text = DomCur->SDomName;
  561.         else
  562.             text = TypeText(DomCur);
  563.         printf(text);
  564.         if (DomCur->ComponentCnt == DomCur->ComponentID)
  565.             printf(");");
  566.     }
  567. }
  568. end procedure CompositeDomains;
  569.  
  570. declare procedure Indices(ID)
  571. argument integer ID;
  572. {
  573.     declare cursor    IndCur;
  574.     declare    integer PrevID;
  575.             
  576.     SELECT    Ind.ID                        AS ID,
  577.             Ind.ComponentID                AS Component,
  578.             Tab.Name                    AS TableName,
  579.             Obj.Name                    AS IndexName,
  580.             Col.Name                    AS ColumnName
  581.     FROM    System.SysIndexComps        AS Ind,
  582.             System.SysObjects            AS Tab,
  583.             System.SysObjects            AS Obj,
  584.             System.SysColumns            AS Col
  585.     WHERE    Ind.DBTableID                == {'Tab', :ID}
  586.     AND        Ind.DBTableID                == Tab.DBID
  587.     AND        Ind.DBColumnID                == Col.DBColumnID
  588.     AND        Ind.DBID                    == Obj.DBID
  589.     ORDER     BY ID ASC, Component ASC
  590.     INTO    IndCur FOR EXTRACT;
  591.     
  592.     PrevID            = 0;
  593.     for each IndCur
  594.     {
  595.         if (IndCur->ID != PrevID)
  596.         {
  597.             if (PrevID != 0)
  598.                 printf (");");
  599.             print "";
  600.             printf("CREATE INDEX %s ON %s (", 
  601.                 IndCur->IndexName, IndCur->TableName);
  602.         }
  603.         if (IndCur->Component != 1)
  604.             printf(", ");
  605.         printf (IndCur->ColumnName);
  606.         PrevID    = IndCur->ID;
  607.     }
  608.     if (PrevID != 0)
  609.         printf (");");
  610. }
  611. end procedure Indices;
  612.  
  613.  
  614. declare procedure SimpleColumns(ID)
  615. argument integer ID;
  616. {
  617.     declare cursor ColCur;
  618.     declare varchar text;
  619.     
  620.     SELECT    Col.ColumnID            AS ColumnID,
  621.             Col.Name                AS ColName,
  622.             Col.Nulls                AS ColNulls,
  623.             Col.Scale                AS Scale,
  624.             Col.Length                AS Length,
  625.             Dom.Name                AS DomName,
  626.             Type.Name                AS TypeName,
  627.             Type.Scale                AS TypeWithScale,
  628.             Type.Length                AS TypeWithLength
  629.     FROM    System.SysColumns        AS Col,
  630.             System.SysObjects        AS Dom,
  631.             System.SysDataTypes        AS Type
  632.     WHERE    Col.DBID                == {'Tab', :ID}
  633.     AND        Col.ColumnID            <  256
  634.     AND        Col.DBDomainID            /= Dom.DBID
  635.     AND        Col.DataType            /= Type.DataType
  636.     ORDER    BY ColumnID ASC
  637.     INTO    ColCur FOR READONLY;
  638.  
  639.     for each ColCur
  640.     {
  641.         if (ColCur->ColumnID != 1)
  642.             printf(",");
  643.         print "";
  644.         printf("    %-20s ", ColCur->ColName);
  645.         if (ColCur->DomName is not null)
  646.             text = ColCur->DomName;
  647.         else
  648.             text = TypeText(ColCur);
  649.         printf("%-20s ", text);
  650.         if (ColCur->ColNulls)
  651.             printf(" NULL");
  652.         else
  653.             printf(" NOT NULL");
  654.     }
  655. }
  656. end procedure SimpleColumns;
  657.  
  658.  
  659. declare procedure CompositeColumns(ID)
  660. argument integer ID;
  661. {
  662.     declare cursor ColCur;
  663.     declare varchar text;
  664.     
  665.     SELECT    Comp.ColumnID            AS ColumnID,
  666.             Comp.ComponentID        AS ComponentID,
  667.             CCol.Name                AS CColName,
  668.             CCol.ComponentCnt        AS ComponentCnt,
  669.             SCol.Name                AS SColName,
  670.             CDom.Name                AS DomName
  671.     FROM    System.SysColumnComps    AS Comp,
  672.             System.SysColumns        AS CCol,
  673.             System.SysColumns        AS SCol,
  674.             System.SysObjects        AS CDom
  675.     WHERE    Comp.Type                == 'Tab'
  676.     AND        Comp.ID                    == :ID
  677.     AND        Comp.DBColumnID            == CCol.DBColumnID
  678.     AND        Comp.DBCompColID        == SCol.DBColumnID
  679.     AND        CCol.DBDomainID            /= CDom.DBID
  680.     ORDER     BY ColumnID ASC, ComponentID ASC
  681.     INTO    ColCur FOR READONLY;
  682.     
  683.     for each ColCur
  684.     {
  685.         if (ColCur->ComponentID == 1)
  686.         {
  687.             printf(",");
  688.             print "";
  689.             printf("    %-20s (", ColCur->CColName);
  690.         }
  691.         else
  692.             printf(", ");
  693.         printf(ColCur->SColName);
  694.         if (ColCur->ComponentID == ColCur->ComponentCnt)
  695.         {
  696.             if (ColCur->DomName is not null)
  697.                 printf(") %s", ColCur->DomName);
  698.             else
  699.                 printf(")");
  700.         }
  701.     }
  702. }
  703. end procedure CompositeColumns;
  704.  
  705. declare procedure Keys(ID)
  706. argument integer ID;
  707. {
  708.     declare cursor    KeyCur, RefCur;
  709.     declare varchar    TypeName;
  710.     
  711.     /*    print the create statements for PRIMARY and CANDIDATE keys of table ID    */
  712.     SELECT    Cols.Name                AS ColName, 
  713.             KeyObj.Name                AS KeyName,
  714.             Keys.KeyType             AS KeyType,
  715.             TabObj.Name                AS TabName
  716.     FROM    System.SysKeys            AS Keys,
  717.             System.SysObjects        AS KeyObj,
  718.             System.SysObjects        AS TabObj,
  719.             System.SysColumns        AS Cols
  720.     WHERE    Keys.DBTableID            == {'Tab', :ID}
  721.     AND        Keys.KeyType            IN ('Pk','Ck')
  722.     AND        Keys.DBID                == KeyObj.DBID
  723.     AND        Keys.DBTableID            == TabObj.DBID
  724.     AND        Keys.DBColumnID         == Cols.DBColumnID
  725.     ORDER     BY KeyType DESC
  726.     INTO    KeyCur FOR READONLY;
  727.     
  728.     for each KeyCur 
  729.     {
  730.         if (KeyCur->KeyType == 'Pk')
  731.             TypeName = "PRIMARY";
  732.         else
  733.             TypeName = "CANDIDATE";
  734.         print "";
  735.         printf("CREATE %s KEY %s ON %s.%s;", 
  736.                 :TypeName, KeyCur->KeyName, KeyCur->TabName, KeyCur->ColName);
  737.     }    
  738.     /*    print the create statements for FOREIGN keys of table ID    */
  739.     SELECT    Keys.ID                    AS KeyID,
  740.             Keys.ReferenceCnt        AS ReferenceCnt,
  741.             Keys.DBColumnID,
  742.             Cols.Name                AS ColName, 
  743.             KeyObj.Name                AS KeyName,
  744.             Keys.UpdateAction        AS UpdateAction,
  745.             Keys.DeleteAction        AS DeleteAction,
  746.             TabObj.Name                AS TabName
  747.     FROM    System.SysKeys            AS Keys,
  748.             System.SysObjects        AS KeyObj,
  749.             System.SysObjects        AS TabObj,
  750.             System.SysColumns        AS Cols
  751.     WHERE    Keys.DBTableID            == {'Tab', :ID}
  752.     AND        Keys.KeyType            == 'Fk'
  753.     AND        Keys.DBID                == KeyObj.DBID
  754.     AND        Keys.DBTableID            == TabObj.DBID
  755.     AND        Keys.DBColumnID         == Cols.DBColumnID
  756.     ORDER     BY KeyID ASC
  757.     INTO    KeyCur FOR READONLY;
  758.     
  759.     for each KeyCur 
  760.     {
  761.         print "";
  762.         printf("CREATE FOREIGN KEY %s ON %s.%s", 
  763.                 KeyCur->KeyName, KeyCur->TabName, KeyCur->ColName);
  764.         if (KeyCur->ReferenceCnt)
  765.         {
  766.             /*    get explicit defined references    */
  767.             SELECT    Refs.ReferenceID        AS RefID,
  768.                     TabObj.Name                AS TabName
  769.             FROM    System.SysReferences    AS Refs,
  770.                     System.SysObjects        AS TabObj
  771.             WHERE    Refs.DBID                == {'Key', KeyCur->KeyID}
  772.             AND        Refs.DBTableID            == TabObj.DBID
  773.             ORDER     BY RefID ASC
  774.             INTO    RefCur FOR READONLY;
  775.             
  776.             printf(" REFERENCES ");
  777.             for each RefCur
  778.             {
  779.                 if (RefCur->RefID != 1)
  780.                     printf(", ");
  781.                 printf(RefCur->TabName);
  782.             }
  783.         }
  784.         else
  785.         {
  786.             declare boolean first = $true;
  787.             /*    get implicit defined references    */
  788.             /*    find a table where the domain of the primary key column is equal 
  789.             **    to the domain of the foreign key column.
  790.             **    
  791.             */
  792.             SELECT    TabObj.Name                AS TabName
  793.             FROM    System.SysColumns        AS FKCols,
  794.                     System.SysKeys            AS PKeys,
  795.                     System.SysColumns        AS PKCols,
  796.                     System.SysObjects        AS TabObj
  797.             WHERE    FKCols.DBColumnID        == {KeyCur->TableType, KeyCur->TableID, KeyCur->ColumnID}
  798.             AND        FKCols.DBDomainID        == PKCols.DBDomainID
  799.             AND        PKCols.DBColumnID        == PKeys.DBColumnID
  800.             AND        PKeys.KeyType            == 'Pk'
  801.             AND        PKeys.DBTableID            == TabObj.DBID
  802.             INTO    RefCur FOR READONLY;
  803.             
  804.             printf(" /* (IMPLICITLY) REFERENCES ");
  805.             for each RefCur
  806.             {
  807.                 if (not first)
  808.                     printf(", ");
  809.                 first = $false;
  810.                 printf(RefCur->TabName);
  811.             }
  812.             printf(" */");
  813.         }    
  814.                 
  815.                 
  816.         if (KeyCur->UpdateAction != 'Rest')
  817.         {
  818.             printf(" ON UPDATE ");
  819.             switch(KeyCur->UpdateAction)
  820.             {
  821.                 case 'Casc': printf("CASCADE"); break;
  822.                 case 'Null': printf("SET NULL"); break;
  823.                 case 'Def':  printf("SET DEFAULT"); break;
  824.             }
  825.         }
  826.         if (KeyCur->DeleteAction != 'Rest')
  827.         {
  828.             printf(" ON DELETE ");
  829.             switch(KeyCur->DeleteAction)
  830.             {
  831.                 case 'Casc': printf("CASCADE"); break;
  832.                 case 'Null': printf("SET NULL"); break;
  833.                 case 'Def':  printf("SET DEFAULT"); break;
  834.             }
  835.         }
  836.         printf(";");
  837.     }    
  838. }
  839. end procedure Keys;
  840.  
  841.  
  842. declare procedure ShowViewText(ID)
  843. argument integer ID;
  844. {
  845.     declare cursor    ViewCur;
  846.     varchar vt;
  847.     integer pos = 0, br = 0;
  848.             
  849.     SELECT    Viewtext
  850.     FROM    System.SysViews
  851.     WHERE    SysViews.ID    == :ID
  852.     INTO    ViewCur FOR EXTRACT;
  853.     fetch next of ViewCur;
  854.     
  855.     print "";
  856.     vt = $toupper(ViewCur->ViewText);
  857.  
  858.     if($locate(vt, $format("\r")) != 0 or $locate(vt, $format("\n")) != 0)
  859.     {
  860.         /*
  861.         If the view contains carriage returns,
  862.         we assume that it does not need formatting
  863.         */
  864.         printf(vt);
  865.         return;
  866.     }
  867.  
  868.     printf("CREATE VIEW ");
  869.     
  870.     pos = $locate(vt, "VIEW");
  871.     vt = $ltrim($substr(vt, pos+4));
  872.     pos = $locate(vt, "AS ");
  873.     printf($substr(vt, 1, pos+1));
  874.     print "";
  875.     vt = $ltrim($substr(vt, pos+3));
  876.     pos = $locate(vt, "FROM ");
  877.     printf($substr(vt, 1, pos-1));
  878.     print "";
  879.     vt = $ltrim($substr(vt, pos));
  880.     pos = $locate(vt, "WHERE");
  881.     if(pos = 0)
  882.         printf(vt);
  883.     else
  884.     {
  885.         /*
  886.         This loop doesn't check for brackets,
  887.         every AND will start a new line
  888.         */
  889.         while (pos > 0)
  890.         {
  891.             printf($substr(vt, 1, pos-1));
  892.             vt = $ltrim($substr(vt, pos));
  893.             pos = $locate(vt, " AND");
  894.             if(pos > 0)
  895.                 print "";
  896.         }
  897.         print "";
  898.         printf(vt);
  899.     }
  900. }
  901. end procedure ShowViewText;
  902.  
  903.  
  904. declare procedure Schema(Name, args)
  905. argument varchar Name = "";            /*    Name of a exiting table    */ 
  906. argument varchar args = "DIRKT";        /*    list of arguments        */
  907. {
  908.     declare        
  909.     varchar    Type; 
  910.     integer    ID, IsView = 0;
  911.     cursor    ObjCur;
  912.     
  913.     if(Name = "")
  914.     {
  915.         SchemaHelp();
  916.         return;
  917.     }
  918.  
  919.     ObjCur = NameToID(:Name);
  920.     if ($rows(ObjCur) == 0)
  921.     {
  922.         print "The object '" + :Name + "' does not exist";
  923.         return;
  924.     }
  925.     if (ObjCur->Type != 'Tab')
  926.     {
  927.         if(ObjCur->Type == 'View')
  928.             IsView = 1;
  929.         else
  930.             return;
  931.     }
  932.         
  933.     ID     = ObjCur->ID;
  934.     Name= ObjCur->CreatorName+"."+ObjCur->Name;
  935.  
  936.     DESELECT ObjCur;
  937.  
  938.     print "";
  939.     print "";
  940.     printf ("/******** %s ********/", :Name);
  941.  
  942.     if (IsView = 1)
  943.         ShowViewText(:ID);
  944.     else
  945.     {
  946.         args = $toupper(args);
  947.         if ($locate(args, "D") != 0)
  948.         {
  949.             SimpleDomains(:ID);
  950.             CompositeDomains(:ID);
  951.         }
  952.         if ($locate(args, "T") != 0)
  953.         {
  954.             print "";
  955.             print "";
  956.             printf("CREATE TABLE %s ", :Name);
  957.             print "";
  958.             printf ("(");
  959.             SimpleColumns(:ID);
  960.             CompositeColumns(:ID);
  961.             print "";
  962.             printf(");");
  963.         }
  964.         if ($locate(args, "K") != 0)
  965.             Keys(:ID);
  966.         if ($locate(args, "R") != 0)
  967.             TableRuleDefault(:ID);
  968.         if ($locate(args, "I") != 0)
  969.             Indices(:ID);
  970.     }
  971.     print "";
  972. }
  973. end procedure Schema;
  974.  
  975.  
  976. declare procedure xref(Name, primaryonly)
  977. argument varchar Name  = $null;
  978. argument boolean primaryonly = $false;
  979. {
  980.     cursor    ObjCur;
  981.  
  982.     ObjCur = NameToID(:Name);
  983.     if ($rows(ObjCur) == 0)
  984.         return;
  985.     if (ObjCur->Type == 'Tab')
  986.     {
  987.         if (primaryonly)
  988.         {
  989.             SELECT    DomObj.Name            AS DomainName,
  990.                     Keys.KeyType        AS Key,
  991.                     TabObjB.Name        AS TableName,
  992.                     ColB.Name            AS ColumnName
  993.             FROM    
  994.                     System.SysKeys        AS PKeys,            /*    Primary keys                */
  995.                     System.SysColumns    AS ColC,            /*    Columns of primary keys        */
  996.                     System.SysColumns    AS ColA,            /*    Columns of given table    */
  997.                     System.SysDomains    AS Dom,
  998.                     System.SysObjects    AS DomObj,
  999.                     System.SysColumns    AS ColB,            /*    Columns of tables with same domain    */
  1000.                     System.SysObjects    AS TabObjB,
  1001.                     System.SysKeys        AS Keys
  1002.             WHERE    ColA.DBID            == {ObjCur->Type, ObjCur->ID}
  1003.             AND        ColA.DBDomainID        == Dom.DBID
  1004.             AND        Dom.DBID            == DomObj.DBID
  1005.             AND        ColB.DBDomainID        == Dom.DBID
  1006.             AND        ColB.DBID            == TabObjB.DBID
  1007.             AND        ColB.DBColumnID        /= Keys.DBColumnID
  1008.             AND        PKeys.KeyType        == 'Pk'
  1009.             AND        PKeys.DBColumnID    == ColC.DBColumnID
  1010.             AND        ColC.DBDomainID        == ColA.DBDomainID
  1011.             ORDER BY DomainName, Key DESC, TableName, ColumnName
  1012.             INTO    ObjCur FOR EXTRACT;
  1013.         }
  1014.         else
  1015.         {
  1016.             SELECT    DomObj.Name            AS DomainName,
  1017.                     Keys.KeyType        AS Key,
  1018.                     TabObjB.Name        AS TableName,
  1019.                     ColB.Name            AS ColumnName
  1020.             FROM    
  1021.                     System.SysColumns    AS ColA,            /*    Columns of given table    */
  1022.                     System.SysDomains    AS Dom,
  1023.                     System.SysObjects    AS DomObj,
  1024.                     System.SysColumns    AS ColB,            /*    Columns of tables with same domain    */
  1025.                     System.SysObjects    AS TabObjB,
  1026.                     System.SysKeys        AS Keys
  1027.             WHERE    ColA.DBID            == {ObjCur->Type, ObjCur->ID}
  1028.             AND        ColA.DBDomainID        == Dom.DBID
  1029.             AND        Dom.DBID            == DomObj.DBID
  1030.             AND        ColB.DBDomainID        == Dom.DBID
  1031.             AND        ColB.DBID            == TabObjB.DBID
  1032.             AND        ColB.DBColumnID        /= Keys.DBColumnID            
  1033.             ORDER BY DomainName, Key DESC, TableName, ColumnName
  1034.             INTO    ObjCur FOR EXTRACT;
  1035.         }
  1036.         showall(ObjCur);
  1037.     }
  1038.     else if (ObjCur->Type == 'Dom')
  1039.     {
  1040.         SELECT    ObjCur->Name        AS DomainName,
  1041.                 Keys.KeyType        AS Key,
  1042.                 TabObjB.Name        AS TableName,
  1043.                 ColB.Name            AS ColumnName
  1044.         FROM    System.SysColumns    AS ColB,
  1045.                 System.SysObjects    AS TabObjB,
  1046.                 System.SysKeys        AS Keys
  1047.         WHERE    ColB.DBDomainID        == {ObjCur->Type, ObjCur->ID}
  1048.         AND        ColB.DBID            == TabObjB.DBID
  1049.         AND        ColB.DBColumnID        /= Keys.DBColumnID
  1050.         ORDER BY Key DESC, TableName, ColumnName
  1051.         INTO    ObjCur FOR EXTRACT;
  1052.         showall(ObjCur);
  1053.     }
  1054. }
  1055. end procedure xref;
  1056. /*schema("");*/
  1057.  
  1058.